#include "stm32f4xx_hal.h"
#include "EC20.h"
#include "usart.h"
#include "user_config.h"
#include <stdio.h>
#include "stdarg.h"
#include "string.h"

#define ProductKey          "a1YUTHIvj3a"             //产品KEY
#define DeviceName          "LED01"      //
#define DeviceSecret        "wC7QfkPw6sZAOHmYJ4ZghGevZdXXSzsC"  //
#define PubTopic         "/sys/a1YUTHIvj3a/LED01/thing/event/property/post"
#define SubTopic        "/sys/a1YUTHIvj3a/LED01/thing/service/property/set"


uint8_t USART1_data;
uint8_t USART2_data;
char UART1_buf[1024];
char UART2_buf[1024];
unsigned short UART1_cnt = 0;
unsigned short UART2_cnt = 0;
unsigned short UART2_cntPre = 0;
static UART_HandleTypeDef   *UART_Handle_Array[5];

/**
 *@breief	清空缓存
 *@param	None
 *@reval	None 
 *@notice	None
 */
void UART_Clear(void)
{
	memset(UART2_buf, 0, sizeof(UART2_buf));
	UART2_cnt = 0;
}

/**
 *@breief	等待接收完成
 *@param	None
 *@reval	REV_OK-接收完成		REV_WAIT-接收超时未完成 
 *@notice	循环调用检测是否接收完成
 */
_Bool UART_WaitRecive(void)
{
	if(UART2_cnt == 0) 							//如果接收计数器为0 则说明处于接受中
		return REV_WAIT;		
	if(UART2_cnt == UART2_cntPre)					//和上次值相同 则说明接收完成
	{
		UART2_cnt = 0;								//清0接收计数			
		return REV_OK;								//返回接收标志
	}	
	UART2_cntPre = UART2_cnt;						//置为相同	
	return REV_WAIT;								//返回接收未完成
}


/**
 *@breief	发送命令
 *@param	cmd命令
			res需要检查返回指令
 *@reval	0-成功	1-失败
 *@notice	None
 */
_Bool UART_SendCmd(uint8_t num,char *cmd, char *res, uint16_t timeout)
{	
	unsigned char timeOut = timeout;
	//UART_Printf(1, cmd);	//单独使用这个函数时，去掉注释
  LOG("\r\n#####\r\nCMD:%s#####\r\n",cmd);
	while(timeOut--)
	{
		if(UART_WaitRecive() == REV_OK)							
		{
      LOG("\r\n*****\r\nlog:%s*****\r\n",UART2_buf);	
			if(strstr((const char *)UART2_buf, res) != NULL)		
			{
				UART_Clear();									
				
				return 0;
			}
		}
		
		HAL_Delay(1);
	}	
  UART_Clear();	
	return 1;
}

void UART_PortConfig(uint8_t num, UART_HandleTypeDef *h_uart)
{
  UART_Handle_Array[num-1] = h_uart; 
    h_uart->RxXferCount = 1;
    h_uart->RxState = HAL_UART_STATE_BUSY_RX;
  /* Enable the UART Parity Error Interrupt */
  __HAL_UART_ENABLE_IT(h_uart, UART_IT_PE);
  /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
  __HAL_UART_ENABLE_IT(h_uart, UART_IT_ERR);
  /* Enable the UART Data Register not empty Interrupt */
  __HAL_UART_ENABLE_IT(h_uart, UART_IT_RXNE);
}

void Usart_SendString(uint8_t num, uint8_t *str)
{
  unsigned int k=0;
  uint8_t usart_num = num -1;
  do 
  {
      HAL_UART_Transmit(UART_Handle_Array[usart_num],(uint8_t *)(str + k) ,1,1000);
      k++;
  } while(*(str + k)!='\0'); 
}

uint16_t UART_SendData(uint8_t num, uint8_t *dat, uint16_t len)
{
    int r = 0;
    if (num > 0 && num <= 5 && dat != NULL && len > 0) {
          HAL_UART_Transmit(UART_Handle_Array[num - 1], dat, len,1000);
        //HAL_UART_Transmit_IT(UART_Handle_Array[num - 1], dat, len);
        r = len;
    }
    return r;
}

uint16_t UART_Printf(uint8_t num, char *format, ...)
{
  uint16_t sent = 0;
  if (num > 0 && num <= 5 && format != NULL) {
    unsigned char UsartPrintfBuf[296];
    va_list ap;
    unsigned char *pStr = UsartPrintfBuf;
    va_start(ap, format);
    vsnprintf((char *)UsartPrintfBuf, sizeof(UsartPrintfBuf), format, ap);							
    sent = strlen((const char *)pStr);
    sent = UART_SendData(num, (uint8_t *)pStr, sent);      
  }
  return sent;
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
//	if(huart->Instance==USART1)
//	{
//		while((USART1->SR&0X40)==0){;}
//        if(UART1_cnt >= sizeof(UART1_buf))	UART1_cnt = 0; //防止串口数据溢出
//        UART1_buf[UART1_cnt++] = USART1_data;       
//		HAL_UART_Receive_IT(&huart1,&USART1_data,1);
//	}
  if(huart->Instance==USART2)
	{
		while((USART2->SR&0X40)==0){;}
        if(UART2_cnt >= sizeof(UART2_buf))	UART2_cnt = 0; //防止串口数据溢出
        UART2_buf[UART2_cnt++] = USART2_data;       
		HAL_UART_Receive_IT(&huart2,&USART2_data,1);
	}
}

at_result_t at_cmd(at_t *at, uint8_t uart_port,char *cmd, char *res, uint16_t time_out)
{
    at->write(uart_port,(uint8_t *)cmd);
    if (res == NULL)
        return AT_OK;
    if (at->check(uart_port,cmd, res, time_out) == 0)
    {
        return AT_OK;
    }
    return AT_ERR;
}

static at_t at = {
    UART_SendCmd,
    Usart_SendString};
#define AT_CMD(a, b, c, d) at_cmd(&at, a, b, c, d)

void MQTT_PublishQs0(char *data)   
{
	while(AT_CMD(EC20_UART_PORT,"AT+QMTPUBEX=0,0,0,0,\"/sys/a1YUTHIvj3a/LED01/thing/event/property/post\",102\r\n",">",200))
	HAL_Delay(1);
  UART_Printf(EC20_UART_PORT, "%s",data);	
  if(!UART_SendCmd(2,"publish_ACK","+QMTPUBEX: 0,0,0",200)){
    LOG("publish successful\r\n");
  }else{
    LOG("publish fail\r\n");
  }
  UART_Clear();
}
///**
// *@breief	初始化
// *@param	None
// *@reval	None 
// *@notice	None
// */ 
    
void EC20_Init(void)
{  
	UART_Clear();
	
	while(AT_CMD(EC20_UART_PORT,"AT\r\n","OK",200))
	HAL_Delay(1);
 
  while(AT_CMD(EC20_UART_PORT,"ATE0\r\n",NULL,200))
  HAL_Delay(1);
  
  while(AT_CMD(EC20_UART_PORT,"AT+CPIN?\r\n","+CPIN: READY",200))					
	HAL_Delay(1);
  
  while(AT_CMD(EC20_UART_PORT,"AT+CGATT?\r\n","+CGATT: 1",200))
  HAL_Delay(1);
  
  while(AT_CMD(EC20_UART_PORT,"AT+CREG?\r\n","+CREG: 0,1",200))		
	HAL_Delay(1);
  
  while(AT_CMD(EC20_UART_PORT,"AT+CSQ\r\n",NULL,200))
	HAL_Delay(1);	
  
  while(AT_CMD(EC20_UART_PORT,"AT+QMTCFG=\"recv/mode\",0,0,1\r\n","OK",200))	
	HAL_Delay(1);

  while(AT_CMD(EC20_UART_PORT,"AT+QMTCFG=\"aliauth\",0,\"a1YUTHIvj3a\",\"LED01\",\"wC7QfkPw6sZAOHmYJ4ZghGevZdXXSzsC\"\r\n","OK",200))//OK
	HAL_Delay(1);

  while(AT_CMD(EC20_UART_PORT,"AT+QMTOPEN=0,\"iot-as-mqtt.cn-shanghai.aliyuncs.com\",1883\r\n","+QMTOPEN: 0,0",200))//"+QMTOPEN: 0,0"
	HAL_Delay(1);

  while(AT_CMD(EC20_UART_PORT,"AT+QMTCONN=0,\"LED01\"\r\n","+QMTCONN: 0,0,0",200))//"+QMTCONN: 0,0,0"
	HAL_Delay(1);						
	
  while(AT_CMD(EC20_UART_PORT,"AT+QMTSUB=0,1,\"/sys/a1YUTHIvj3a/LED01/thing/service/property/set\",0\r\n","+QMTSUB: 0,1,0,1",200))//"+QMTSUB: 0,1,0,1"
	HAL_Delay(1);		
  LOG("EC20 Init Finish\r\n");
	UART_Clear();
}


